const downloadsRepo = require('../db/repositories/downloadsRepo');
const logsRepo = require('../db/repositories/logsRepo');
const { childWithReqId } = require('../utils/logger');
const { validateDownloadInput } = require('../utils/validator');
const jobService = require('../services/jobService');

function getReqId(req) {
    return req.headers['x-request-id'] || null;
}

async function create(req, res) {
    const reqId = getReqId(req);
    const log = childWithReqId(reqId);
    try {
        const payload = req.body || {};
        const validation = validateDownloadInput(payload);
        if (!validation.ok) {
            return res.status(400).json({ error: 'invalid_payload', details: validation.errors });
        }
        const { id } = jobService.createJob(payload, reqId);
        return res.status(201).json({ id });
    } catch (err) {
        log.error({ err }, 'create job failed');
        return res.status(500).json({ error: 'internal_error' });
    }
}

async function trigger(req, res) {
    const reqId = getReqId(req);
    const log = childWithReqId(reqId);
    const { id } = req.params;
    if (!id) return res.status(400).json({ error: 'missing_id' });
    try {
        const job = await jobService.runJob(id, reqId);
        return res.json(job);
    } catch (err) {
        if (err && err.code === 'NOT_FOUND') return res.status(404).json({ error: 'not_found' });
        log.error({ err }, 'run job failed');
        return res.status(500).json({ error: 'internal_error' });
    }
}

function getOne(req, res) {
    const { id } = req.params;
    if (!id) return res.status(400).json({ error: 'missing_id' });
    const job = downloadsRepo.getById(id);
    if (!job) return res.status(404).json({ error: 'not_found' });
    return res.json(job);
}

function list(req, res) {
    const { status, limit, offset } = req.query;
    const parsedLimit = Number(limit) || 50;
    const parsedOffset = Number(offset) || 0;
    const data = status
        ? downloadsRepo.listByStatus(String(status), parsedLimit, parsedOffset)
        : downloadsRepo.listAll(parsedLimit, parsedOffset);
    return res.json({ items: data });
}

function logs(req, res) {
    const { id } = req.params;
    if (!id) return res.status(400).json({ error: 'missing_id' });
    const { limit, offset } = req.query;
    const parsedLimit = Number(limit) || 200;
    const parsedOffset = Number(offset) || 0;
    const items = logsRepo.listLogs(id, parsedLimit, parsedOffset);
    return res.json({ items });
}

module.exports = {
    create,
    trigger,
    getOne,
    list,
    logs,
};


